package cn.edu.seu.ssny.controller.web;

import cn.edu.seu.ssny.common.ExportExcelUtils;
import cn.edu.seu.ssny.common.JsonResult;
import cn.edu.seu.ssny.common.R;
import cn.edu.seu.ssny.common.utils.DateUtils;
import cn.edu.seu.ssny.common.utils.FileUtils;
import cn.edu.seu.ssny.controller.BaseController;
import cn.edu.seu.ssny.entity.*;
import cn.edu.seu.ssny.service.*;
import cn.edu.seu.ssny.service.specification.SimpleSpecificationBuilder;
import cn.edu.seu.ssny.service.specification.SpecificationOperator;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.Index;
import javax.persistence.criteria.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Controller
@RequestMapping("/web/project")
public class WebController extends BaseController {
    private final static Logger logger = LoggerFactory.getLogger(WebController.class);

    @Value("${file.uploadFolder}")
    private String fileUploadFolder;

    @Value("${file.url}")
    private String fileUrl;

    @Autowired
    private IProjectService projectService;

    @Autowired
    private IAlarmService alarmService;

    @Autowired
    private IDeviceService deviceService;

    @Autowired
    private IDeviceDataService deviceDataService;

    @Autowired
    private IDeviceDataStdService deviceDataStdService;

    @Autowired
    private IEquipmentService equipmentService;

    @Autowired
    private ISelfControllerImageService selfControllerImageService;

    @Autowired
    private ISysClassService sysClassService;


    @RequestMapping(value = {"/index"})
    public String index(HttpSession session) {
        return "web/map";
    }

    @RequestMapping(value = {"/{id}"})
    public String index(@PathVariable Integer id, HttpSession session) {
        Project currProject = projectService.find(id);
        session.setAttribute("currProject", currProject);
        return "web/map";
    }


    @RequestMapping(value = {"/detail"})
    public String detail(HttpSession session) {
        return "web/detail";
    }


    private void setAirMap(String equipmentName, String returnName, ModelMap map) {
        Optional<Equipment> equipment = equipmentService.findByName(equipmentName);
        String s1 = "";
        s1 += getDataByEquipmentDeviceName("温度", equipment);
        s1 += "&nbsp;";
        s1 += getDataByEquipmentDeviceName("PM2.5", equipment);
        map.put(returnName + "1", s1);
        String s2 = "";
        s2 += getDataByEquipmentDeviceName("相对湿度", equipment);
        s2 += "&nbsp;";
        s2 += getDataByEquipmentDeviceName("二氧化碳", equipment);
        map.put(returnName + "2", s2);
    }

    @RequestMapping(value = {"/air"})
    public String airIndex(ModelMap map, HttpSession session) {
        Project project = (Project) session.getAttribute("currProject");
        setAirMap("空气质量检测1", "l1", map);
        setAirMap("空气质量检测2", "l2", map);
        setAirMap("空气质量检测3", "l3", map);
        setAirMap("空气质量检测4", "l4", map);
        setAirMap("空气质量检测5", "l5", map);
        return "web/air";
    }

    @RequestMapping(value = {"/alarm"})
    public String alarmIndex(ModelMap map) {
        return "web/alarm/index";
    }

    public BigInteger convertTime(String timeString) throws ParseException {
        SimpleDateFormat sdfmat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdfmatNew = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = sdfmat.parse(timeString);
        return new BigInteger(sdfmatNew.format(date));
    }

    @RequestMapping(value = {"/alarm/list"})
    @ResponseBody
    public Page<Alarm> alarmList(HttpSession session) throws ParseException {
        Project project = (Project) session.getAttribute("currProject");
        SimpleSpecificationBuilder<Alarm> builder = new SimpleSpecificationBuilder<Alarm>();
        builder.add("project", SpecificationOperator.Operator.eq.name(), project);
        String startTimeSearch = request.getParameter("startTimeSearch");
        String endTimeSearch = request.getParameter("endTimeSearch");
        String categorySearch = request.getParameter("categorySearch");
        String keySearch = request.getParameter("keySearch"); //关键字，名字
//        System.out.println(startTimeSearch);
//        System.out.println(endTimeSearch);
//        System.out.println(categorySearch);
//        System.out.println(keySearch);
        if (StringUtils.isNotBlank(startTimeSearch)) {
            builder.add("createTime", SpecificationOperator.Operator.timeGe.name(), startTimeSearch);
        }
        if (StringUtils.isNotBlank(endTimeSearch)) {
            builder.add("createTime", SpecificationOperator.Operator.timeLe.name(), endTimeSearch);
        }
        if (StringUtils.isNotBlank(categorySearch)) {
            builder.add("category", SpecificationOperator.Operator.eq.name(), categorySearch);
        }
        if (StringUtils.isNotBlank(keySearch)) {
            builder.add("name", SpecificationOperator.Operator.likeAll.name(), keySearch);
        }
        Sort sort = new Sort("status").and(new Sort(Sort.Direction.DESC, "createTime"));
        Page<Alarm> page = alarmService.findAll(builder.generateSpecification(), getPageRequest(sort));
        return page;
    }


    @RequestMapping(value = "alarm/add", method = RequestMethod.GET)
    public String alarmAdd(ModelMap map, HttpSession session) {
        Project project = (Project) session.getAttribute("currProject");
        List<Device> alarmPoint = deviceService.findAlarmDevices(project);
        map.put("devices", alarmPoint);
        return "web/alarm/form";
    }

    @RequestMapping(value = "alarm/edit/{id}", method = RequestMethod.GET)
    public String alarmEdit(@PathVariable Integer id, ModelMap map) {
        Alarm alarm = alarmService.find(id);
        map.put("alarm", alarm);
        return "web/alarm/form";
    }

    @RequestMapping(value = "alarm/create", method = RequestMethod.POST)
    @ResponseBody
    public JsonResult alarmCreate(ModelMap map, HttpSession session) {
        Project project = (Project) session.getAttribute("currProject");
        String device_id = request.getParameter("device_id");
        try {
            Device device = deviceService.find(Integer.parseInt(device_id));
            Alarm alarm = new Alarm();
            alarm.setCreateTime(new Date());
            alarm.setName(device.getName());
            alarm.setEnterprise(project.getEnterprise());
            alarm.setProject(project);
            alarmService.create(alarm);
        } catch (Exception e) {
            return JsonResult.failure(e.getMessage());
        }
        return JsonResult.success();
    }

    @RequestMapping(value = "alarm/address/{id}", method = RequestMethod.GET)
    public String alarmAddress(@PathVariable Integer id, ModelMap map) {
        Alarm alarm = alarmService.find(id);
        map.put("alarm", alarm);
        return "web/alarm/address";
    }

    @RequestMapping(value = {"alarm/edit"}, method = RequestMethod.POST)
    @ResponseBody
    public JsonResult alarmAddress(Alarm alarm, ModelMap map, HttpSession session) {
        try {
            alarmService.address(alarm);

        } catch (Exception e) {
            return JsonResult.failure(e.getMessage());
        }
        return JsonResult.success();
    }

    /*运维管理-设备保养界面*/
    @RequestMapping(value = {"/maintain"})
    public String maintainIndex(HttpSession session, ModelMap map) {
        Project project = super.getCurrProject(session);
        Long projectId = Long.valueOf(project.getId());
        List<SysClass> sysClasses = sysClassService.findAllByProjectId(projectId);
        map.put("sysClasses", sysClasses);
        map.put("project", project);
        return "web/maintain/index";
    }

    /*运维管理-设备保养界面-显示列表*/
    @RequestMapping(value = {"/maintain/list"})
    @ResponseBody
    public Page<Equipment> list(HttpSession session) throws ParseException {
        Project project = (Project) session.getAttribute("currProject");
        SimpleSpecificationBuilder<Equipment> builder = new SimpleSpecificationBuilder<Equipment>();
        builder.add("project", SpecificationOperator.Operator.eq.name(), project);
        String keySearch = request.getParameter("keySearch"); //关键字，名字
        if (StringUtils.isNotBlank(keySearch)) {
            builder.add("name", SpecificationOperator.Operator.likeAll.name(), keySearch);
        }
        String sysType = request.getParameter("sysType"); //系统分类
        if (StringUtils.isNotBlank(sysType)) {
            builder.add("sysType", SpecificationOperator.Operator.likeAll.name(), sysType);
        }
        Sort sort = new Sort("isMaintain").and(new Sort("name"));
        Page<Equipment> page = equipmentService.findAll(builder.generateSpecification(), getPageRequest(sort));
        List<Equipment> equipments = page.getContent();

        return page;
    }


    /*运维管理-设备保养界面-导出报表*/
    @RequestMapping(value = "/maintain/export")
    public void exportReport(HttpServletResponse response, HttpSession session) {
        //表头数据
        String[] header = {"设备名称", "型号", "系统分类", "启用时间", "上次保养时间", "管理人", "下次保养时间", "保养状态"};
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String sheetName = "equipment_maintain_" + df.format(new Date());

        //声明一个工作簿
        HSSFWorkbook workbook = new HSSFWorkbook();

        //在工作簿中声明一个sheet 默认名称为 设备保养报表-时间
        HSSFSheet sheet = workbook.createSheet(sheetName);

        //创建标题样式
        HSSFCellStyle headerStyle = workbook.createCellStyle();
        headerStyle.setFillForegroundColor(IndexedColors.YELLOW.index);
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        //创建第一行表头
        HSSFRow headrow = sheet.createRow(0);

        //遍历表头，向其中添加数据
        for (int i = 0; i < header.length; i++) {
            //创建一个单元格
            HSSFCell cell = headrow.createCell(i);
            //创建一个内容对象
            HSSFRichTextString text = new HSSFRichTextString(header[i]);
            //将内容对象和表头样式写入cell中
            cell.setCellValue(text);
            cell.setCellStyle(headerStyle);
        }

        HSSFCellStyle redStyle = workbook.createCellStyle();
        redStyle.setFillForegroundColor(IndexedColors.RED.index);

        HSSFCellStyle greenStyle = workbook.createCellStyle();
        greenStyle.setFillForegroundColor(IndexedColors.GREEN.index);

        Project currProject = (Project) session.getAttribute("currProject");
        //获取项目下的设备维护信息
        List<Equipment> equipments = equipmentService.findByProject(currProject);
        for (int i = 0; i < equipments.size(); i++) {
            HSSFRow row = sheet.createRow(i + 1);
            Equipment equipment = equipments.get(i);
            //存放设备名
            try {
                row.createCell(0).setCellValue(StringUtils.defaultIfBlank(equipment.getName(), "-"));
            } catch (Exception e) {
                row.createCell(0).setCellValue("-");
                logger.info(e.getMessage());
            }
            //存放设备型号
            try {
                if (equipment.getType() == null || equipment.getType().getTypeName() == null || equipment.getType().getTypeName().getName() == null) {
                    row.createCell(1).setCellValue("-");
                } else {
                    row.createCell(1).setCellValue(StringUtils.defaultIfBlank(equipment.getType().getTypeName().getName(), "-"));
                }
            } catch (Exception e) {
                row.createCell(1).setCellValue("-");
                logger.info(e.getMessage());
            }

            //存放系统分类
            try {
                if (equipment.getSysType() == null) {
                    row.createCell(2).setCellValue("-");
                } else {
                    row.createCell(2).setCellValue(StringUtils.defaultIfBlank(equipment.getSysType(), "-"));
                }
            } catch (Exception e) {
                row.createCell(2).setCellValue("-");
                logger.info(e.getMessage());
            }


            //存放启用时间
            try {
                if (equipment.getOpenTime() == null) {
                    row.createCell(3).setCellValue("-");
                } else {
                    row.createCell(3).setCellValue(StringUtils.defaultIfBlank(DateUtils.format(equipment.getOpenTime(), "yyyy-MM-dd HH:mm:ss"), "-"));
                }
            } catch (Exception e) {
                row.createCell(3).setCellValue("-");
                logger.info(e.getMessage());
            }

            //存放上次保养时间
            try {
                if (equipment.getLastMaintainTime() == null) {
                    row.createCell(4).setCellValue("-");
                } else {
                    row.createCell(4).setCellValue(StringUtils.defaultIfBlank(DateUtils.format(equipment.getLastMaintainTime(), "yyyy-MM-dd HH:mm:ss"), "-"));

                }
            } catch (Exception e) {
                row.createCell(4).setCellValue("-");
                logger.info(e.getMessage());
            }

            //存放管理人
            try {
                row.createCell(5).setCellValue(StringUtils.defaultIfBlank(equipment.getManager(), "-"));
            } catch (Exception e) {
                row.createCell(5).setCellValue("-");
                logger.info(e.getMessage());
            }
            //存放下次保养时间
            row.createCell(6).setCellValue("-");
            //存放保养状态
            try {
                if (equipment.getIsMaintain() == null || !equipment.getIsMaintain()) {
                    HSSFCell cell1 = row.createCell(7);
                    cell1.setCellValue("未保养");
                    cell1.setCellStyle(redStyle);
                } else {
                    HSSFCell cell0 = row.createCell(7);
                    cell0.setCellValue("已保养");
                    cell0.setCellStyle(greenStyle);
                }
            } catch (Exception e) {
                HSSFCell cell1 = row.createCell(7);
                cell1.setCellValue("未保养");
                cell1.setCellStyle(redStyle);
                logger.info(e.getMessage());
            }

        }
        //准备将Excel的输出流通过response输出到页面下载
        //八进制输出流
        response.setContentType("application/octet-stream");
        //这后面可以设置导出Excel的名称，此例中名为student.xls
        response.setHeader("Content-disposition", "attachment;filename=" + sheetName + ".xls");
        try {
            //刷新缓冲
            response.flushBuffer();
            //workbook将Excel写入到response的输出流中，供页面下载
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            logger.info(e.getMessage());
        }
    }


    @RequestMapping(value = "maintain/edit/{id}", method = RequestMethod.GET)
    public String maintainEdit(@PathVariable Integer id, ModelMap map) {
        Equipment equipment = equipmentService.find(id);
        map.put("equipment", equipment);
        return "web/maintain/form";
    }

    @RequestMapping(value = {"maintain/edit"}, method = RequestMethod.POST)
    @ResponseBody
    public JsonResult maintainEdit(Equipment equipment, ModelMap map, HttpSession session) {
        try {
            equipmentService.setMaintainTime(equipment);

        } catch (Exception e) {
            return JsonResult.failure(e.getMessage());
        }
        return JsonResult.success();
    }


    @RequestMapping(value = {"/maintain/address/{equipmentId}"}, method = RequestMethod.POST)
    @ResponseBody
    public JsonResult maintainAddress(@PathVariable Integer equipmentId, ModelMap map, HttpSession session) {
        try {
            equipmentService.maintain(equipmentId);

        } catch (Exception e) {
            return JsonResult.failure(e.getMessage());
        }
        return JsonResult.success();
    }

    /**
     * 功能描述:
     * <返回展示保养流程图界面
     *
     * @param session
     * @param map
     * @return
     */
    @GetMapping("/maintain/show_maintain_image")
    public String showImage(HttpSession session, ModelMap map) {
        Project project = getCurrProject(session);
        map.put("project", project);
        return "web/maintain/show_maintain_image";
    }

    /**
     * 功能描述:
     * <返回上传保养流程图界面
     *
     * @return
     */
    @GetMapping("/maintain/upload_maintain_image")
    public String uploadMaintainImageHtml() {
        return "web/maintain/upload_maintain_image";
    }

    /**
     * 功能描述:
     * <上传保养流程图，并且保存到数据库中
     *
     * @param file
     * @param session
     * @return
     * @throws IOException
     */
    @ResponseBody
    @PostMapping("/maintain/upload_maintain_image")
    public R uploadMaintainImage(MultipartFile file, HttpSession session) throws IOException {
        Project project = getCurrProject(session);
        String newFileName = FileUtils.upload(file, fileUploadFolder);
        project.setMaintainImgSrc(fileUrl + newFileName);
        projectService.save(project);
        session.setAttribute("project", project);
        return R.ok();
    }

    /**
     * 功能描述:
     * <删除保养流程图
     *
     * @param session
     * @return
     */
    @ResponseBody
    @DeleteMapping("/maintain/delete_maintain_image")
    public R deleteMaintainImage(HttpSession session) {
        Project project = getCurrProject(session);
        project.setMaintainImgSrc(null);
        projectService.save(project);
        session.setAttribute("project", project);
        return R.ok();
    }


    /*自控策略 打开界面 并且查看自控制策略图*/
    @RequestMapping("/selfcontroller")
    public String selfController(HttpSession session, Model model) {
        Project project = getCurrProject(session);
        SelfControllerImage image = selfControllerImageService.getByProject(project);
        //得到图片的路径
        if (image == null || StringUtils.isBlank(image.getImagePath())) {
            //说明该项目的 自控策略图不存在
            model.addAttribute("exist", 0);
        } else {
            //说明该项目 自控策略图存在
            model.addAttribute("exist", 1);
        }
        return "web/selfcontroller/index";
    }

    /*在前端展示 自控策略图*/
    @RequestMapping("/selfcontroller/show_image")
    public void showImage(HttpServletResponse response, HttpSession session) {
        Project project = (Project) session.getAttribute("currProject");
        SelfControllerImage image = selfControllerImageService.getByProject(project);
        //得到图片的路径
        response.setContentType("image/jpeg/jpg/png/gif/bmp/tiff/svg");
        String path = image.getImagePath();
        File file = new File(fileUploadFolder + path);
        if (file.exists()) {
            try {
                FileInputStream in = new FileInputStream(file);
                OutputStream os = response.getOutputStream();
                byte[] b = new byte[1024];
                while (in.read(b) != -1) {
                    os.write(b);
                }
                in.close();
                os.flush();
                os.close();
            } catch (IOException e) {
                logger.info(e.getMessage());
            }
        }
    }

    /**
     * 上传自控策略图
     *
     * @param file
     * @param session
     * @return
     */
    @PostMapping("/selfcontroller/upload_image")
    @ResponseBody
    public R uploadImage(@RequestParam(value = "file") MultipartFile file, HttpSession session) throws IOException {
        String newFileName = FileUtils.upload(file, fileUploadFolder);
        selfControllerImageService.save((Project) session.getAttribute("currProject"), newFileName);
        return R.ok();

    }

    /*删除自控制策略图*/
    @ResponseBody
    @RequestMapping("/selfcontroller/remove_image")
    public JsonResult removeImage(HttpSession session) {

        int code = 0;
        String message;
        try {
            selfControllerImageService.deleteByProject((Project) session.getAttribute("currProject"));
            message = "success";
        } catch (Exception e) {
            logger.info(e.getMessage());
            code = 500;
            message = e.getMessage();
        }
        if (code == 0) {
            return JsonResult.success(message);
        }
        return JsonResult.failure(code, message);

    }


    public String getDataByDeviceName(String name, Project project) {
        Optional<Device> device = deviceService.findByNameAndProject(name, project);
        if (device.isPresent()) {
            Optional<DeviceData> deviceData = deviceDataService.findFirstByDeviceOrderByCreateTimeDesc(device.get());
            if (deviceData.isPresent()) {
                String data = Double.toString(deviceData.get().getData());
                return data + device.get().getTemplate().getTag();
            }
        }
        return "-";
    }

    public String getDataByEquipmentDeviceName(String name, Optional<Equipment> equipment) {
        if (!equipment.isPresent())
            return name + ":-";
        Optional<Device> device = deviceService.findByEquipmentAndDescriptionLike(equipment.get(), name);
        if (device.isPresent()) {
            Optional<DeviceDataStd> deviceDataStd = deviceDataStdService.findFirstByDeviceOrderByCreateTimeDesc(device.get());
            if (deviceDataStd.isPresent()) {
                String data = Double.toString(deviceDataStd.get().getData());
                return name + ":" + data + device.get().getTemplate().getTag();
            }
        }
        return name + ":-";
    }

    @RequestMapping(value = "device", method = RequestMethod.GET)
    public String dataDisplay(ModelMap map, HttpSession session) {
        ArrayList<String> dataList = new ArrayList<>();
        Project project = getCurrProject(session);
        displayDevices(map, project, dataList);
        map.put("dataList", dataList);
        map.put("dryOutdoor", getDataByDeviceName("室外温度", project));
        map.put("moistOutdoor", getDataByDeviceName("室外湿度", project));
        map.put("beam", getDataByDeviceName("太阳辐射强度", project));
        return "web/display";
    }

    @RequestMapping(value = "device/{projectID}/{equipmentID}", method = RequestMethod.GET)
    public String dataDisplayFromSlide(@PathVariable Integer projectID, @PathVariable Integer equipmentID,
                                       ModelMap map, HttpSession session) {
        Project project = projectService.find(projectID);
        session.setAttribute("currProject", project);
        ArrayList<String> dataList = new ArrayList<>();
        displayDevices(map, project, dataList);
        Equipment equipment = equipmentService.find(equipmentID);
        map.put("equipment", equipment);
        map.put("dataList", dataList);
        map.put("dryOutdoor", getDataByDeviceName("室外温度", project));
        map.put("moistOutdoor", getDataByDeviceName("室外湿度", project));
        map.put("beam", getDataByDeviceName("太阳辐射强度", project));
        return "web/display";
    }

    private void displayDevices(ModelMap map, Project project, ArrayList<String> dataList) {
        List<Device> devices = deviceService.findByProject(project);
        List<Equipment> equipments = project.getEquipments();
        for (Device device : devices) {
            dataList.add("-");
        }
        map.put("alarmCount", 0);
        map.put("devices", devices);
        map.put("equipments", equipments);
    }

    @RequestMapping(value = {"/livedata"})
    public String liveDataIndex(ModelMap map) {
        return "web/data/livedata";
    }

    @RequestMapping(value = {"device/data"}, method = RequestMethod.GET)
    @ResponseBody
    public JsonResult dataList(ModelMap map, HttpSession session) {
        ArrayList<DeviceData> dataList = new ArrayList<>();
        try {
            Project project = (Project) session.getAttribute("currProject");
            List<Device> deviceList = deviceService.findByProject(project);
            for (Device device : deviceList) {
                Optional<DeviceData> deviceData = deviceDataService.findFirstByDeviceOrderByCreateTimeDesc(device);
                deviceData.ifPresent(dataList::add); //添加进列表的简易lambda表达式
            }
        } catch (Exception e) {
            return JsonResult.failure(e.getMessage());
        }
        return JsonResult.success("0", dataList);
    }

    @RequestMapping(value = {"device/alarmcount"}, method = RequestMethod.GET)
    @ResponseBody
    public JsonResult alarmCount(ModelMap map, HttpSession session) {
        int alarmCount = 0;
        try {
            Project project = (Project) session.getAttribute("currProject");
            alarmCount = alarmService.countAlarmsByProjectAndStatus(project, false);
            System.out.println(alarmCount);
        } catch (Exception e) {
            return JsonResult.failure(e.getMessage());
        }
        return JsonResult.success("0", alarmCount);

    }


    private Specification<DeviceData> dataList(Project project) {
        String startTimeSearch = request.getParameter("startTimeSearch");
        String endTimeSearch = request.getParameter("endTimeSearch");
        String keySearch = request.getParameter("keySearch"); //关键字，用户名
        if (project != null) System.out.println(project.getName());
        Specification<DeviceData> specification = new Specification<DeviceData>() {
            @Override
            public Predicate toPredicate(Root<DeviceData> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicatesList = new ArrayList<>();
                Join<DeviceData, Device> joinDevice = root.join("device", JoinType.INNER);
                if (project != null) {
                    predicatesList.add(cb.equal(joinDevice.get("project"), project));
                }
                if (StringUtils.isNotBlank(startTimeSearch))
                    predicatesList.add(cb.greaterThanOrEqualTo(root.get("createTime"), DateUtils.parseDate(startTimeSearch)));
                if (StringUtils.isNotBlank(endTimeSearch))
                    predicatesList.add(cb.lessThanOrEqualTo(root.get("createTime"), DateUtils.parseDate(endTimeSearch)));
                if (StringUtils.isNotBlank(keySearch)) {
                    predicatesList.add(cb.like(joinDevice.get("name"), '%' + keySearch + '%'));
                }
                query.orderBy(cb.desc(root.get("createTime")));
                Predicate[] predicates = new Predicate[predicatesList.size()];
                return cb.and(predicatesList.toArray(predicates));
            }
        };
        return specification;
    }

    @RequestMapping(value = {"/livedata"}, method = RequestMethod.POST)
    @ResponseBody
    public Page<DeviceData> liveDataList(HttpSession session) throws ParseException {
        Page<DeviceData> page = deviceDataService.findAll(dataList((Project) session.getAttribute("currProject")), getPageRequest());
        return page;
    }

    @RequestMapping(value = {"/livedataexport"}, method = RequestMethod.POST)
    @ResponseBody
    public void liveDataExport(HttpSession session) throws Exception {
        ExcelData data = new ExcelData();
        data.setName("liveData");
        List<String> titles = new ArrayList();
        titles.add("序号");
        titles.add("名称");
        titles.add("时间");
        titles.add("数值");
        titles.add("补录数值");
        titles.add("单位");
        data.setTitles(titles);

        List<List<Object>> rows = new ArrayList();
        List<DeviceData> list = deviceDataService.findList(dataList((Project) session.getAttribute("currProject")));
        for (int i = 0; i < list.size(); i++) {
            List<Object> row = new ArrayList();
            row.add(i + 1 + "");
            row.add(list.get(i).getDevice().getName());
            row.add(DateUtils.format(list.get(i).getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
            row.add(list.get(i).getData());
            if (list.get(i).getIsModified())
                row.add(list.get(i).getModifiedData());
            else
                row.add("-");
            row.add(list.get(i).getDevice().getTemplate().getTag());
            rows.add(row);
        }

        data.setRows(rows);
        ExportExcelUtils.exportExcel(response, "liveData.xlsx", data);
    }

    @RequestMapping(value = {"/modifydata"}, method = RequestMethod.POST)
    @ResponseBody
    public Page<DeviceData> modifiedDataList(HttpSession session) throws ParseException {
        Page<DeviceData> page = deviceDataService.findAll(dataList(null), getPageRequest());
        return page;
    }

    @RequestMapping(value = {"/equipment/{id}"})
    public String equipment(@PathVariable Integer id, ModelMap map, HttpSession session) {
        Equipment currEquipment = equipmentService.find(id);
        List<Device> deviceList = new ArrayList<>(currEquipment.getDevices());
        Collections.sort(deviceList);
        ArrayList<String> dataList = new ArrayList<>();
        ArrayList<String> nameList = new ArrayList<>();
        for (Device device : deviceList) {
            nameList.add(device.getName());
            Optional<DeviceData> deviceData = deviceDataService.findFirstByDeviceOrderByCreateTimeDesc(device);
            String data = "-";
            if (deviceData.isPresent()) {
                data = Double.toString(deviceData.get().getData());
                if (deviceData.get().getIsModified())
                    data = Double.toString(deviceData.get().getModifiedData());
            }
            if (device.getTemplate().getIsBin()) {
                try {
                    int dataNum = (int) Double.parseDouble(data);
//                    System.out.println(dataNum);
                    String tail = dataNum == 0 ? device.getTemplate().getBin0() : device.getTemplate().getBin1();
//                    System.out.println(tail);
                    dataList.add(tail);
                } catch (Exception e) {
                    dataList.add("-");
                }
            } else
                dataList.add(data + device.getTemplate().getTag());
        }
        map.put("currEquipment", currEquipment);
        map.put("dataList", dataList);
        map.put("nameList", nameList);
        return "web/equipment";
    }
}
